/*
 * (C) Copyright 2010 Atmark Techno, Inc.
 *
 * Lincoln Zhang <Lincoln_Zhang@gmail.com>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */
#include <signal.h>
#include <errno.h>
//#include <sys/types.h>
//#include <sys/socket.h>
//#include <sys/ioctl.h>
//#include <net/if.h>
#include <unistd.h>
//#include <arpa/inet.h>
#include "cf_std.h"
#include "cf_common.h"
#include "cf_key_value_file.h"
#include "cf_sigfd.h"
#include "cf_timer.h"
#include "cf_shadow_file.h"
#include "cf_passwd_file.h"
#include "cf_fstab_file.h"
#include "cf_cgi.h"
#include "unistd.h"
#include "cf_json.h"
#include "cf_queue.h"
#define USE_MESSAGE_LOG
//#define MESSAGE_LOG_FILE "c://tmp/msg.log"
#define USE_ERROR_LOG
//#define ERROR_LOG_FILE "/tmp/error.log"
#define USE_DEBUG_LOG
//#define DEBUG_LOG_FILE "/tmp/debug.log"
#include "cf_log.h"

//#include "cf_network.h"
/*
int get_name(int fd)
{
    write(fd, CONST_STR_LEN("Lincoln Zhang"));
    return 0;
}

int get_year(int fd)
{
    write(fd, CONST_STR_LEN("23"));
    return 0;
}

int get_sex(int fd)
{
    write(fd, CONST_STR_LEN("boy"));
    return -1;
}

void timer_func1(void* data)
{
    struct timeval exp;
    time_t t;
    exp.tv_sec = 2;
    exp.tv_usec = 0;
    t = time(NULL);
	CF_MSG("timer1: %s", ctime(&t));
    cf_timer_add(&exp, timer_func1, NULL);
	//CF_MSG("clock:%d\n", *(clock_t*)data);
}

void timer_func2(void* data)
{
    struct timeval exp;
    time_t t;
    exp.tv_sec = 5;
    exp.tv_usec = 0;
    t = time(NULL);
	CF_MSG("timer2: %s", ctime(&t));
    cf_timer_add(&exp, timer_func2, NULL);
	//CF_MSG("clock:%d\n", *(clock_t*)data);
}
*/

int TestJson()
{
    int year;
    CFJson* jObj = CFJsonParse("{\"name\":\"chunfeng\", \"year\":21}");
    if(!jObj){
        CF_ERR("NULL json obj\n");
        return -1;
    }
    CF_MSG("name=%s\n", CFJsonObjectGetString(jObj, "name"));
    if(CFJsonObjectGetInt(jObj, "year", &year)){
        CF_ERR("config error: year\n");
        return -1;        
    }
    CF_MSG("year=%i\n", year);
    CFString str;
    CFStringInit(&str, "");
    CFJsonGetString(jObj, &str);
    CF_MSG(CFStringGetStr(&str));
    CFStringExit(&str);
    return 0;
}

int TestFstabFile()
{
    CFFstabFile* fstab = cf_fstab_file_new("./fstab");
    cf_fstab_file_set(fstab, "UUID=BE1C508F1C504495", "/", "ntfs", "defaults", 0, 2);
    cf_fstab_file_print(fstab);
    cf_fstab_file_save(fstab, NULL);
    cf_fstab_file_free(fstab);
    return 0;
}

int TestKeyValueFile()
{
    CFKeyValueFile *conf = cf_key_value_file_new("./rc.conf", '=');
    if(!conf){
        perror("new conf error");
        return -1;
    }
	cf_key_value_file_set(conf, "LOCALE", "\"en_US.utf8\"");
    cf_key_value_file_print(conf);
    cf_key_value_file_set(conf, "LOCALE", "\"zh_CN.utf8\"");
	cf_key_value_file_print(conf);
    printf("LOCALE=%s\n", cf_key_value_file_get(conf, "LOCALE"));
    printf("HARDWARECLOCK=%s\n", cf_key_value_file_get(conf, "HARDWARECLOCK"));
    cf_key_value_file_save(conf, NULL);
    cf_key_value_file_free(conf);
    return 0;
}

int TestKeyValueFile_blank()
{
    CFKeyValueFile *conf = cf_key_value_file_new("./slim.conf", ' ');
    if(!conf){
        perror("new conf error");
        return -1;
    }
	cf_key_value_file_set(conf, "LOCALE", "\"en_US.utf8\"");
    cf_key_value_file_print(conf);
    cf_key_value_file_set(conf, "LOCALE", "\"zh_CN.utf8\"");
	cf_key_value_file_print(conf);
    //printf("LOCALE=%s\n", cf_key_value_file_get(conf, "LOCALE"));
    //printf("HARDWARECLOCK=%s\n", cf_key_value_file_get(conf, "HARDWARECLOCK"));
    cf_key_value_file_save(conf, NULL);
    cf_key_value_file_free(conf);
    return 0;
}

int TestShadowFile()
{
    CFShadowFile* file = cf_shadow_file_new("./shadow");
	if(!file) return -1;
    cf_shadow_file_set_password_by_name(file, "root", "root");
    cf_shadow_file_set_password_by_name(file, "usbmux", "liulijuan");
    cf_shadow_file_print(file);
    cf_shadow_file_save(file, NULL);
    cf_shadow_file_free(file);
    return 0;
}

int TestPasswdFile()
{
    CFPasswdFile* file = cf_passwd_file_new("./passwd");
    CF_DBG("\n");
	if(!file) return -1;
    cf_passwd_file_print(file);
    CF_DBG("\n");
    cf_passwd_file_save(file, NULL);
    CF_DBG("\n");
    cf_passwd_file_free(file);
    return 0;
}

int TestQueue()
{
    int data[100], i;
    CFQueue que;
    int *d;
    
    CFQueueInit(&que, 1000);
    for(i=0; i<sizeof(data)/sizeof(int); i++){
        data[i] = i;
        CFQueuePush(&que, &data[i]);
    }
    for(i=0; i<sizeof(data)/sizeof(int); i++){
        CFQueuePop(&que, (void**)&d);
        CF_MSG("%d\n", *d);
    }
    for(i=0; i<sizeof(data)/sizeof(int); i++){
        data[i] = i;
        CFQueuePush(&que, &data[i]);
    }
    return CFQueueExit(&que);
    
}
#ifdef _ENABLE_BLKID_
#include "cf_blkid.h"
int TestBlkid()
{
    CFJson* disksInfo;
    disksInfo = CFAllDisksInfoNew();
    CF_MSG(CFJsonNewCStr(disksInfo));
    return 0;
}
#endif

int main(int argc, char** argv)
{

	
    /*
    int res;
    CFString *str = cf_string_new("");
    //char * args[]={"thunar", NULL};
    res = cf_file_to_string("/proc/cmdline", str);
    printf("result: %d\n, str=%s", res, cf_string_get_str(str));
    cf_string_free(str);
    cf_system2("ls", "-l", NULL);
	*/
	

	
	/*
    CFString * uuid = cf_string_new("");
    cf_get_disk_uuid("/dev/sda1", uuid);
    puts(cf_string_get_str(uuid));
    cf_string_free(uuid);
    cf_gen_grub2_cfg("./grub.cfg", "/dev/sda7", "/dev/sda6");
    */
    
/*
    char *xx = cf_lltoa(123);
    printf("%lli\n%s\n", cf_atoll_n("12345nml", 5), xx);
    printf("%lli\n%s\n", cf_atoll_n("12345nml", 5), xx);
*/


	/*
	const char* query = "name=chunfeng&sex=male&year=1986";
	CFString* year = cf_string_new("");
	cf_cgi_parse_query(query, "sex", year);
	CF_MSG(cf_string_get_str(year));
	cf_string_free(year);
	*/

/*
	int i =0;
	for(i=0; i<10; i++){
	CF_MSG("%d: test_message_log\n", 1);
	CF_ERR("%d: test_error_log\n", 1);
	CF_DBG("%d: test_debug_log\n", 1);
	}
	cf_log_close_file();
*/
	
/*
    int sigfd, res;
    fd_set fds;
	struct timeval exp;
	clock_t clock_n;
	cf_timers_init();
    sigfd = cf_sigfd_open(SIGHUP, SIGUSR1, SIGINT, SIGALRM, 0);
    if(sigfd == -1){
        return -1;
    }
	clock_n = clock();
	exp.tv_sec = 2;
	exp.tv_usec = 0;
	cf_timer_add(&exp, timer_func1, NULL);
   // cf_timer_add(&exp, timer_func1, NULL);
   // cf_timer_add(&exp, timer_func1, NULL);
    //cf_timer_add(&exp, timer_func1, NULL);
    //cf_timer_add(&exp, timer_func1, NULL);
    //cf_timer_add(&exp, timer_func1, NULL);
    exp.tv_sec = 5;
	exp.tv_usec = 0;
	cf_timer_add(&exp, timer_func2, NULL);
    while(1){
        FD_ZERO(&fds);
        FD_SET(sigfd, &fds);
       // printf("before select\n");
        if(-1 == select(sigfd+1, &fds, NULL, NULL, NULL)){
            if(errno == EINTR){
                //printf("Interrput caused the select exit, We will handle it with cf_sigfd!!\n");
				continue;
            }else{
                    res = -1;
                    goto OUT0;
            }
        }
        if(FD_ISSET(sigfd, &fds)){
            int exit = 0;
            switch(cf_sigfd_get_next_signal(sigfd)){
                case SIGUSR1:
                    printf("Got SIGUSR1\n");
                    break;
                case SIGHUP:
                    printf("Got SIGHUP\n");
                    break;
                case SIGINT:
                    printf("Bye Bye\n");
                    exit = 1;
                    break;
				case SIGALRM:
					//printf("Cot SIGALRM\n");
					cf_timers_trigger();
					break;
                default:
                    printf("Unknown signal\n");
            }
            if(exit){
                res = 0;
                goto OUT0;
            }
        }
    }
    
OUT0:
    cf_sigfd_close();
	cf_timers_clean();
    return res;
	*/

/*
    struct sockaddr_in addr;
    ifconfig_get_addr("eth0", (struct sockaddr*)&addr);
*/

/*
	CFCgiKeyFuncPair* head = cf_cgi_key_func_pair_new("name", get_name);
    cf_cgi_key_func_pair_append(head, "year", get_year);
    cf_cgi_key_func_pair_append(head, "sex", get_sex);
    cf_cgi_display_html("test.htm", head, 1);
    cf_cgi_key_func_pair_free_all(head);
*/

/*
    int sigfd = cf_sigfd_open(SIGHUP, SIGUSR1, SIGINT, 0);
*/
//    TestJson();
//    TestFstabFile();
//    TestKeyValueFile();
//    TestKeyValueFile_blank();
//    TestShadowFile();
//      TestPasswdFile();
//    TestQueue();
#ifdef _ENABLE_BLKID_
    TestBlkid();
#endif

    return 0;
}
